/*
 * fsl_boot.c
 *
 *  Created on: Aug 5, 2019
 *      Author: duan
 */

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "srec.h"
#include "serial.h"
#include "flash.h"
#include "xparameters.h"

#define FLASH_APP_BASEADDR    0x200000
#define TEMP_RAM_START        (XPAR_MCB_DDR3_S0_AXI_BASEADDR + 0x02000000 + 0x100000)
#define TEMP_RBK_START        (XPAR_MCB_DDR3_S0_AXI_BASEADDR + 0x02000000 + 0x200000)
//#define load_mem(x)
#define BOOT_STAGE 0

extern uint8_t rv_buf[SREC_MAX_BYTES + 4];

static void flash_program(uint8_t* mem_src_addr,uint32_t dest_addr_flash,uint32_t size)
{
	uint32_t i,j,k;
    uint8_t *mem_ptr = mem_src_addr;

    fl_addr = dest_addr_flash;
    j=size;
	k = (j + 4095)/4096;
    fl_addr = FLASH_APP_BASEADDR;
    for(i=0;i<k;i++) {
    	flash_sector_erase(&fl_addr);
    	fl_addr = fl_addr + 4096;
    }
    udelay(1000000);

    k = (j + 255)/256;
    fl_addr = FLASH_APP_BASEADDR;
    for(i=0;i<k;i++) {
    	flash_page_write(&fl_addr,&mem_ptr[i*256]);
    	fl_addr = fl_addr + 256;
    }
}

static void flash_boot(uint8_t* mem_src_addr,uint32_t dest_addr_flash,uint32_t size)
{
	uint32_t i,j,k;
    uint8_t *mem_ptr = mem_src_addr;

    fl_addr = dest_addr_flash;
    j=size;
	k = (j + 256)/256;
	for (i = 0; i < k; i++) {
		spi_flash_read(&fl_addr, 256);
		fl_addr = fl_addr + 256;
		memcpy(&mem_ptr[i * 256], &rv_buf[4], 256);
		udelay(1000000);
	}

	load_mem(mem_ptr);
}

int main()
{
    int size;

    serial_init();
    flash_init();

    if (BOOT_STAGE > 0){
    	xil_printf("SBOOT Load binary firmware file:\r\n\r\n\r\n", -1);
    	size = xmodemReceive(TEMP_RAM_START, (8 * 1024 * 1024));
    	if (0 > size) xil_printf("\r\nXmodem receive error!\r\n");
    	udelay(1000000);
    	//load_mem ((uint8_t *)TEMP_RAM_START);
    	flash_program((uint8_t *)TEMP_RAM_START,FLASH_APP_BASEADDR,size);
    }

    fl_addr = FLASH_APP_BASEADDR;
    xil_printf("SBOOT SREC image from flash @ address: %x \r\n",fl_addr);
    if (BOOT_STAGE > 1) flash_boot((uint8_t *)TEMP_RBK_START,FLASH_APP_BASEADDR,size);
    else load_exec ();

    xil_printf ("\r\nERROR!! "); // If we reach here, we are in error
    return 1;
}
